package com.lemurian.bankdata.action.business;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.struts2.ServletActionContext;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;

import com.lemurian.bankdata.dto.LogHelper;
import com.lemurian.bankdata.lite.authentication.BankDataPrincipal;
import com.lemurian.bankdata.lite.enums.UserActivityType;
import com.lemurian.bankdata.lite.enums.UserType;
import com.lemurian.bankdata.lite.logger.BankDataLogger;
import com.lemurian.bankdata.lite.struts.Pager;
import com.lemurian.bankdata.lite.struts.PartialList;
import com.lemurian.bankdata.lite.utils.FormatData;
import com.lemurian.bankdata.lite.utils.GeneralConstant;
import com.lemurian.bankdata.lite.utils.GlobalFunction;
import com.lemurian.bankdata.services.ActivityLogService;
import com.lemurian.bankdata.services.ClientCertificateService;
import com.lemurian.bankdata.services.ClientService;
import com.lemurian.bankdata.services.UserService;
import com.lemurian.bankdata.utils.BaseAction;
import com.lemurian.entity.Client;
import com.lemurian.entity.ClientCertificate;
import com.lemurian.entity.User;
import com.opensymphony.xwork2.Preparable;

public class DaftarKlienPetugasKetikAction extends BaseAction implements Preparable {

	private static final long serialVersionUID = 1L;

	private BankDataLogger log = BankDataLogger.getLogger(DelegasiPengetikanAction.class.getSimpleName());
	
	private Client client = null;
	private List<Client> clients;
	
	private List<ClientCertificate> clientCertificates = new ArrayList<ClientCertificate>();
	private List<String> endTypingDates = new ArrayList<String>();

	private int id = 0, isAdministrator = 0, isDivisionHead = 0;
	
	private String namaKlien = "", petugas = "";
	
	private User user;
	private BankDataPrincipal principal;
	
	@Autowired
	private ClientService clientService;
	@Autowired
	private UserService userService;
	@Autowired
	private ClientCertificateService clientCertificateService;
	
	@Autowired 
	private ActivityLogService userActivityLogService;
	private LogHelper userActivityLog;
	
	@Override
	public void prepare() throws Exception {
		log.info(": : : : : ON DAFTAR KLIEN PETUGAS KETIK ");
		
		principal = (BankDataPrincipal) getSession().get(GeneralConstant.USER_PRINCIPAL);
		user = principal.getUser();
		
		if(user.getUserType().getId() == UserType.ADMINISTRATOR.id()) {
			isAdministrator = 1;
		}
		
		if(user.getUserType().getId() == UserType.KEPALA_DIVISI.id()) {
			isDivisionHead = 1;
		}
	}
	
	@Override
	public String list() {
		setPreviousPage(GeneralConstant.LIST);
		
		try {
			/* LIST CERTIFICATE */
			Criterion criterion = null;
			criterion = Restrictions.isNotNull("officerType.id");
			
			log.info(": : : : : USER TYPE ID "+user.getUserType().getId());
			if(user.getUserType().getId() == UserType.KEPALA_DIVISI.id()) {
				criterion = Restrictions.eq("department.id", user.getDepartment().getId());
			} else {
				criterion = Restrictions.eq("officerType.id", user.getId());
			}
			
			PartialList<Client> partialList = clientService.findByCriteria(getStart(), getCount(), getAscDesc().equalsIgnoreCase("desc") ? Order.desc(getOrderBy().length() > 0 ? getOrderBy() : "id") : Order.asc(getOrderBy().length() > 0 ? getOrderBy() : "id"),
					namaKlien.length() > 0 ? Restrictions.ilike("debitur.name", namaKlien, MatchMode.ANYWHERE) : Restrictions.ne("id", new Integer(-1)),
					//petugas.length() > 0 ? Restrictions.ilike("officerType.name", petugas, MatchMode.ANYWHERE) : Restrictions.ne("id", new Integer(-1)),
					criterion);
			
			clients = partialList.getList();
			log.info("got total client : " + clients.size());
			
			setPager(Pager.generatePager(getStart(), getCount(), partialList.getTotal()));
            setPagerItem(Pager.generatePagerItem(getStart(), getCount(), partialList.getTotal()));

            partialList = null;
			
		} catch (Throwable t) {
			t.printStackTrace();
		}
		
		setMappedRequest(GeneralConstant.LIST);
        return SUCCESS;
	}
	
	@Override
	public String save() {
		
		log.info(": : : : : CLIENT SIZE "+clients.size());
		if(clients != null && clients.size() > 0) {
			
			try {
				for(Client c : clients) {
					log.info(": : : : : CLIENT ID "+ c.getId());
					client = clientService.load(c.getId());
					log.info(": : : : : CLIENT "+ client);
					if(client != null && client.getId() != 0) {
						log.info(":: SAVING CLIENT");
						if (c.getDocumentLocation() != null && !c.getDocumentLocation().trim().equalsIgnoreCase("")) {
							client.setDocumentLocation(c.getDocumentLocation());	
						}
						if (c.getTbo() != null && !c.getTbo().trim().equalsIgnoreCase("")) {
							client.setTbo(c.getTbo());	
						}
						clientService.save(client);
						
						userActivityLog = new LogHelper(user, UserActivityType.LETTER_TYPIS_INPUT_FORM_TBO);
						
			            try {
			                log.sInfo(" :: User [%s:%s] is successfully has been input tbo form of certiciate name [%s]", user.getId(), user.getName(), client.getDebitur().getName());

			                //check if activity is success
			                userActivityLog.setStatus(LogHelper.SUCCESS_ACTIVITY);
			                addCustomActionMessage("Successfully update data of tbo form");
			            } catch (Exception e) {
			                log.sInfo(" :: Error was raised when User [%s:%s] input tbo form of certiciate name [%s]", user.getId(), user.getName(), client.getDebitur().getName());
			                
			                //set activity log status into failed
			                userActivityLog.setStatus(LogHelper.FAILED_ACTIVITY);
			                userActivityLog.setErrorMsg(e.getMessage());
			                addCustomActionMessage("Failed update data of tbo form. Message : " + e.getMessage());
			            }
			            //save activity log
			            userActivityLog.setSessionId(ServletActionContext.getRequest().getSession().getId());
			            userActivityLog.getAdditionalParams().add(client.getDebitur().getName());
			            userActivityLogService.saveUserActivity(userActivityLog);
					} 
				}
				
			} catch (Throwable t) {
				addCustomActionError("Failed input tbo form");
				t.printStackTrace();
			}
		} else {
			addCustomActionError("Failed input tbo form");
		}
		
		setMappedRequestFullPath("/DaftarKlienPetugasKetikAction_list.do");
		return GeneralConstant.REDIRECT;
	}
	
	public String form() {
		setPreviousPage("form");
		
		client = clientService.load(id);
		clientCertificates = clientCertificateService.getByClientId(client);
		
		log.info(": : : : : CLIENT CERTIFICATE SIZE "+clientCertificates.size());
		
		setMappedRequest("update");
		
		return SUCCESS;
	}
	
	@Override
	public String update() {
		
		log.info(": : : : : CLIENT CERTIFICATE SIZE "+clientCertificates.size());
		
		ClientCertificate clientCertificate = null;
		
		Date date = null;
		int i = 0;
		for(ClientCertificate cc : clientCertificates) {
			clientCertificate = clientCertificateService.load(cc.getId());
			
			if(clientCertificate != null) {
				try {
					log.info(": : : : : DATE "+endTypingDates.get(i));
					if(endTypingDates.get(i) != null && endTypingDates.get(i).length() > 0) {
						clientCertificate.setEndTypingDate(FormatData.dateFormatShow.parse(endTypingDates.get(i)));
						clientCertificateService.save(clientCertificate);
					}
				} catch (Throwable t) {
					addCustomActionMessage("Failed update data "+client.getDebitur().getName());
					t.printStackTrace();
				}
			}
			i++;
		}
		Client updateClient = client;
		client = clientService.load(client.getId());
		client.setDocumentLocation(updateClient.getDocumentLocation());
		client.setTbo(updateClient.getTbo());
		updateClient = null;
		clientService.save(client);
		
		userActivityLog = new LogHelper(user, UserActivityType.LETTER_TYPIS_INPUT_FORM_TBO);
		
        try {
            log.sInfo(" :: User [%s:%s] is successfully has been input tbo form of certiciate name [%s]", user.getId(), user.getName(), client.getDebitur().getName());

            //check if activity is success
            userActivityLog.setStatus(LogHelper.SUCCESS_ACTIVITY);
        } catch (Exception e) {
            log.sInfo(" :: Error was raised when User [%s:%s] when input tbo form of certiciate name [%s]", user.getId(), user.getName(), client.getDebitur().getName());
            
            //set activity log status into failed
            userActivityLog.setStatus(LogHelper.FAILED_ACTIVITY);
            userActivityLog.setErrorMsg(e.getMessage());
        }
        //save activity log
        userActivityLog.setSessionId(ServletActionContext.getRequest().getSession().getId());
        userActivityLog.getAdditionalParams().add(client.getDebitur().getName());
        userActivityLogService.saveUserActivity(userActivityLog);
		
		addCustomActionMessage("Successfully update data "+client.getDebitur().getName());
		
		setMappedRequestFullPath("/DaftarKlienPetugasKetikAction_list.do");
		return GeneralConstant.REDIRECT;
	}
	
	@Override
	public String detail() {
		setPreviousPage("approve");
		
		client = clientService.load(id);
		clientCertificates = clientCertificateService.getByClientId(client);
		
		log.info(": : : : : CLIENT CERTIFICATE SIZE "+clientCertificates.size());
		
		setMappedRequest("approve");
		return SUCCESS;
	}
	
	public String approve() {
		
		try {
			client = clientService.load(client.getId());
			client.setApproved(Boolean.TRUE);
			clientService.save(client);
			
			userActivityLog = new LogHelper(user, UserActivityType.APPROVAL_MARKETING_HEAD_OF_LETTER_TYPIS);
			
	        try {
	            log.sInfo(" :: User [%s:%s] is successfully has been approved certificate [%s] with letter typis [%s]", user.getId(), user.getName(), client.getDebitur().getName(), client.getOfficerType().getName());

	            //check if activity is success
	            userActivityLog.setStatus(LogHelper.SUCCESS_ACTIVITY);
	        } catch (Exception e) {
	            log.sInfo(" :: Error was raised when User [%s:%s] when approved certificate [%s] with letter typis [%s]", user.getId(), user.getName(), client.getDebitur().getName(), client.getOfficerType().getName());
	            
	            //set activity log status into failed
	            userActivityLog.setStatus(LogHelper.FAILED_ACTIVITY);
	            userActivityLog.setErrorMsg(e.getMessage());
	        }
	        //save activity log
	        userActivityLog.setSessionId(ServletActionContext.getRequest().getSession().getId());
	        userActivityLog.getAdditionalParams().add(client.getDebitur().getName());
	        userActivityLog.getAdditionalParams().add(client.getOfficerType().getName());
	        userActivityLogService.saveUserActivity(userActivityLog);
			
			addCustomActionMessage("Successfully approve "+client.getDebitur().getName());
		} catch (Throwable t) {
			addCustomActionMessage("Failed approve "+client.getDebitur().getName());
			t.printStackTrace();
		}
		 
		setMappedRequestFullPath("/DaftarKlienPetugasKetikAction_list.do");
		return GeneralConstant.REDIRECT;
	}
	
	@Override
	public String add() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public String delete() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public String edit() {
		// TODO Auto-generated method stub
		return null;
	}

	public List<Client> getClients() {
		return clients;
	}

	public void setClients(List<Client> clients) {
		this.clients = clients;
	}

	public String getNamaKlien() {
		return namaKlien;
	}

	public void setNamaKlien(String namaKlien) {
		this.namaKlien = namaKlien;
	}

	public String getPetugas() {
		return petugas;
	}

	public void setPetugas(String petugas) {
		this.petugas = petugas;
	}

	public Client getClient() {
		return client;
	}

	public void setClient(Client client) {
		this.client = client;
	}

	public int getId() {
		return id;
	}

	public void setId(String id) {
		int id_ = 0;
		if(id != null && !id.equalsIgnoreCase("0")) {
			id = GlobalFunction.decodeParameter(id);
	        id_ = Integer.parseInt(id);
		}
        this.id = id_;
	}

	public List<ClientCertificate> getClientCertificates() {
		return clientCertificates;
	}

	public void setClientCertificates(List<ClientCertificate> clientCertificates) {
		this.clientCertificates = clientCertificates;
	}

	public List<String> getEndTypingDates() {
		return endTypingDates;
	}

	public void setEndTypingDates(List<String> endTypingDates) {
		this.endTypingDates = endTypingDates;
	}

	public int getIsAdministrator() {
		return isAdministrator;
	}

	public void setIsAdministrator(int isAdministrator) {
		this.isAdministrator = isAdministrator;
	}

	public int getIsDivisionHead() {
		return isDivisionHead;
	}

	public void setIsDivisionHead(int isDivisionHead) {
		this.isDivisionHead = isDivisionHead;
	}
	
	
	
}